#include "ccd290_extract.h"

void extract_ccd_data(char fname[]) {

    unsigned short udata_E, udata_E_;
    unsigned short udata_F, udata_F_;
    unsigned short udata_G, udata_G_;
    unsigned short udata_H, udata_H_;

    unsigned short data_E, data_F, data_G, data_H;

    FILE *fb = fopen(fname,"rb");

/*    int num = LEN*2*4;	// total number of chars*/
/*    unsigned char *regs = (unsigned char*)malloc(sizeof(unsigned char)*num);*/
/*    fread(regs, sizeof(unsigned char), num, fb);*/

    int num = LEN*4;	// total number of chars
    unsigned short *regs = (unsigned short*)malloc(sizeof(unsigned short)*num);
    fread(regs, sizeof(unsigned short), num, fb);

    fclose(fb);

    uint16_t *ch_E, *ch_F, *ch_G, *ch_H;
    ch_E = (uint16_t*)malloc(sizeof(uint16_t)*LEN);
    ch_F = (uint16_t*)malloc(sizeof(uint16_t)*LEN);
    ch_G = (uint16_t*)malloc(sizeof(uint16_t)*LEN);
    ch_H = (uint16_t*)malloc(sizeof(uint16_t)*LEN);

    int i,j;
    int cnt=0;
    for(i=0; i<num; i+=4) {

        udata_E = regs[i+0];
        udata_F = regs[i+1];
        udata_G = regs[i+2];
        udata_H = regs[i+3];

        j = i+4;
        if( j < num ) {

            udata_E_ = regs[j+0];
            udata_F_ = regs[j+1];
            udata_G_ = regs[j+2];
            udata_H_ = regs[j+3];

        //	shift 4-bits to recover original LTC2271 AD outputs
            unsigned short E, F, G, H;
            E = ((udata_E & 0x0fff) << 4) | ((udata_E_ & 0xf000) >> 12);
            F = ((udata_F & 0x0fff) << 4) | ((udata_F_ & 0xf000) >> 12);
            G = ((udata_G & 0x0fff) << 4) | ((udata_G_ & 0xf000) >> 12);
            H = ((udata_H & 0x0fff) << 4) | ((udata_H_ & 0xf000) >> 12);

/*			E = udata_E;*/
/*			F = udata_F;*/
/*			G = udata_G;*/
/*			H = udata_H;*/

            data_E = fun2s(E);
            data_F = fun2s(F);
            data_G = fun2s(G);
            data_H = fun2s(H);

            ch_E[cnt] = data_E;
            ch_F[cnt] = data_F;
            ch_G[cnt] = data_G;
            ch_H[cnt] = data_H;

            cnt++;
            
/*            if( i<500){*/
/*            	printf("%6d %6d %6d %6d\n", data_E, data_F, data_G, data_H);*/
/*            	printf("%6u %6u %6u %6u\n", data_E, data_F, data_G, data_H);*/
/*            }*/
        }
    }
    
/*    printf("@DEBUG cnt = %d\n", cnt);*/

//	CDS
    uint16_t *ccd = (uint16_t*)malloc(sizeof(uint16_t)*N_ROW*N_COL*4);
    
    for(i=0; i<N_ROW*N_COL*4; i++) ccd[i] = 0;

	// uint offset = 11-7;	// for real CCD290 data
	uint offset = 10;
/*    uint offset = 75-3*21 ;*/
    int row=0,col=0;

    //  For test
    // uint idx1 = 0;
    // uint idx2 = 1;
    // uint idx3 = 4;
    // uint idx4 = 5;
    
    //  for CCD290
    uint E_idx1 = 2;
    uint E_idx2 = 8;
    uint E_idx3 = 11;
    uint E_idx4 = 17;

    uint F_idx1 = 2;
    uint F_idx2 = 8;
    uint F_idx3 = 11;
    uint F_idx4 = 17;
    
    uint G_idx1 = 2;
    uint G_idx2 = 8;
    uint G_idx3 = 11;
    uint G_idx4 = 17;
    
    uint H_idx1 = 2;
    uint H_idx2 = 8;
    uint H_idx3 = 11;
    uint H_idx4 = 17;

//	DEBUG
/*	printf("SAMP_PER_REG = %d\n", SAMP_PER_REG);*/
/*	exit(0);*/

    double size = 7;
    
    int idx;
    for(idx=offset; idx<LEN-4; idx+=SAMP_PER_REG) {

        int idxE = row*N_COL*2 + col;
        int idxF = row*N_COL*2 + (N_COL*2-col-1);
        int idxG = (N_ROW*2-row-1)*N_COL*2 + col;
        int idxH = (N_ROW*2-row-1)*N_COL*2 + (N_COL*2-col-1);
        
        int sumE1=0, sumE2=0;
        int sumF1=0, sumF2=0;
        int sumG1=0, sumG2=0;
        int sumH1=0, sumH2=0;

		int cnt;
		for( cnt=E_idx1; cnt<=E_idx2; cnt++ ) sumE1 += (int)ch_E[idx+cnt];
		for( cnt=E_idx3; cnt<=E_idx4; cnt++ ) sumE2 += (int)ch_E[idx+cnt];

		for( cnt=F_idx1; cnt<=F_idx2; cnt++ ) sumF1 += (int)ch_F[idx+cnt];
		for( cnt=F_idx3; cnt<=F_idx4; cnt++ ) sumF2 += (int)ch_F[idx+cnt];

		for( cnt=G_idx1; cnt<=G_idx2; cnt++ ) sumG1 += (int)ch_G[idx+cnt];
		for( cnt=G_idx3; cnt<=G_idx4; cnt++ ) sumG2 += (int)ch_G[idx+cnt];

		for( cnt=H_idx1; cnt<=H_idx2; cnt++ ) sumH1 += (int)ch_H[idx+cnt];
		for( cnt=H_idx3; cnt<=H_idx4; cnt++ ) sumH2 += (int)ch_H[idx+cnt];

        ccd[idxE] = (uint16_t)( ( sumE1 - sumE2 ) / size );
        ccd[idxF] = (uint16_t)( ( sumF1 - sumF2 ) / size );
        ccd[idxG] = (uint16_t)( ( sumG1 - sumG2 ) / size );
        ccd[idxH] = (uint16_t)( ( sumH1 - sumH2 ) / size );
        
	//	write test data into ccd[]
/*		ccd[idxE] = row;*/
/*		ccd[idxF] = row;*/
/*		ccd[idxG] = col;*/
/*		ccd[idxH] = col;*/

    	col++;  // 必须先+1,然后再进行判断
        if(col >= N_COL) {
            col = 0;
            row++;
        }

/*        if(col >= (N_COL-1)) {*/
/*            col = 0;*/
/*            row++;*/
/*        }*/

        /*		printf("idx = %ld, row = %d, col = %d\n", idx, row, col);*/
    }


    FILE *fp = fopen("fig.txt","w");
    for(row=0; row<N_ROW*2; row++) {
        for(col=0; col<N_COL*2; col++) {
            fprintf(fp,"%7d ", ccd[row*N_COL*2+col]);
        }
        fprintf(fp,"\n");
    }
    fclose(fp);


//	===================================================
    fitsfile *fptr;
    int status;
    long fpixel = 1, naxis = 2, nelements, exposure;
    long naxes[2] = {N_COL*2, N_ROW*2}; // image is 300 pixel wide by 200 rows
/*    long naxes[2] = {N_ROW*2, N_COL*2}; // image is 300 pixel wide by 200 rows*/
    
/*    unsigned short *array[N_ROW*2];*/
/*    int ii,jj;*/
/*    for(ii=0; ii<N_ROW*2; ii++){*/
/*    	array[ii] = */
/*    }*/

    status = 0;
    fits_create_file(&fptr, "tmp.fits", &status); /* create new file */

    /*Create the primary array image (16-bit short uinteger pixels) */
    /*	fits_create_img(fptr, SHORT_IMG, naxis, naxes, &status);*/
    fits_create_img(fptr, USHORT_IMG, naxis, naxes, &status);

    /*Write a keyword; must pass the ADDRESS of the value */
    exposure = 1500.;
    fits_update_key(fptr, TLONG, "EXPOSURE", &exposure, "Total Exposure Time", &status);
    nelements = naxes[0] * naxes[1];

    /* Write the array of integers to the image */
    /*	fits_write_img(fptr, TSHORT, fpixel, nelements, ccd, &status);*/
    fits_write_img(fptr, TUSHORT, fpixel, nelements, ccd, &status);

    fits_close_file(fptr, &status);

    fits_report_error(stderr, status);
//	===================================================


    free(regs);
    free(ccd);
}


